﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using KBEngine.Common;

namespace KBEngine
{
    public class clientapp
    {
        Machines _machine;
        private Machines machines
        {
            get
            {
                if (_machine == null)
                {
                    var port = GetFreePort();
                    if (port == 0) throw new NotSupportedException();
                    _machine = new Machines(listenPort: port);
                }
                return _machine;
            }
        }
        public List<ComponentInfo> MachineList { get => machines.machines; }

        /// <summary>
    /// 初始化KBEngineCore
    /// </summary>
        public bool Init()
        {
            return LogicEvents.Check(); //事件重名检测
        }

        /// <summary>
        /// 使用界面框架中的计时器在主线程调用此方法(建议20毫秒调用一次)
        /// </summary>
        public void Tick()
        {
            // 处理外层抛入的事件
            Event.processInEvents();
            Event.processOutEvents();
        }

        /// <summary>
        /// 查找所有守护进程信息
        /// </summary>
        /// <returns>找到则返回true</returns>
        public void QueryAllMachineInfos()
        {
            machines.QueryAllInterfaces();
        }

        /// <summary>
        /// 根据MachineID获取所管理的所有app信息
        /// </summary>
        public List<ComponentInfo> GetAppInfos(uint machineID)
        {
            if(!machines.interfaces_groups.TryGetValue(machineID, out var value))
                value = new List<ComponentInfo>();
            return value;
        }

        public void StartServer(ComponentType componentType, string kbe_root, string kbe_res_path, string kbe_bin_path)
        {
            machines.StartServer(componentType, machines.makeCID(componentType), machines.makeGUS(componentType), null, kbe_root, kbe_res_path, kbe_bin_path);
        }
        public void StopServer(ComponentType componentType)
        {
            machines.StopServer(componentType);
        }
        public void KillServer(ComponentType componentType)
        {
            machines.KillServer(componentType);
        }

        private ushort GetFreePort()
        {
            IList portUsed = PortIsUsed();
            for (ushort port = 1025; port < Math.Pow(2, sizeof(ushort) * 8); ++port)
            {
                if (!portUsed.Contains(port))
                    return port;
            }
            return 0;
        }
        private IList PortIsUsed()
        {
            //获取本地计算机的网络连接和通信统计数据的信息
            IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();

            //返回本地计算机上的所有Tcp监听程序
            IPEndPoint[] ipsTCP = ipGlobalProperties.GetActiveTcpListeners();

            //返回本地计算机上的所有UDP监听程序
            IPEndPoint[] ipsUDP = ipGlobalProperties.GetActiveUdpListeners();

            //返回本地计算机上的Internet协议版本4(IPV4 传输控制协议(TCP)连接的信息。
            TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();

            IList allPorts = new ArrayList();
            foreach (IPEndPoint ep in ipsTCP) allPorts.Add(ep.Port);
            foreach (IPEndPoint ep in ipsUDP) allPorts.Add(ep.Port);
            foreach (TcpConnectionInformation conn in tcpConnInfoArray) allPorts.Add(conn.LocalEndPoint.Port);

            return allPorts;
        }
    }
}
